; filelog - log all actions performed on any files
; copyright abandoned 2000,  Kiwi Software (Luke Graham)
; Version 0.0.3,  last updated 23/02/2000 (lrg)

; this is a /quick/ hack to log all actions that are performed on files
; it requires SysLog by Jon Ribbens
; many thanks to Jon for writing SysLog which made this /so/ much easier.

 AREA	|filelog|, CODE

 ;GET	h.SWIs

 ;GET "FileLogger:s.osfiledata"
 ;GET "FileLogger:s.osbgetdata"
 ;GET "FileLogger:s.osbputdata"
 ;GET "FileLogger:s.osfinddata"
 ;GET "FileLogger:s.osgbpbdata"
 ;GET "FileLogger:s.osargsdata"
 ;GET "FileLogger:s.osfscdata"


			ENTRY
moduleBase		DCD	0
			DCD	initCode
			DCD	finalCode
			DCD	0
			DCD	titleString
			DCD	helpString
			DCD	0
			DCD	0
			DCD	0
			DCD	0
			DCD	0
			DCD	0

titleString		DCB	"FileLogger", 0
helpString		DCB	"FileLogger", 9, "0.03 (23 Feb 2000) Kiwi Software (lrg)", 0
			ALIGN

initCode		stmfd	r13!,{r0-r5,r12,r14}

			;expand Log path for testing
			mov	r0,#37		; canonicalise path
			adr	r1,logNameS
			adr	r2,pathCheckBuffer
			adr	r3,logPathS
			mov	r4,#0
			mov	r5,#255
			swi	OS_FSControl

			;write and read char routines?

			mov	r0,#8		;OS_FileV
			adr	r1,fileVLogRoutine
			mov	r2,#8
			swi	OS_Claim

			mov	r0,#9		;OS_ArgV
			adr	r1,argVLogRoutine
			mov	r2,#9
			swi	OS_Claim

			mov	r0,#&A		;OS_BGetV
			adr	r1,bgetVLogRoutine
			mov	r2,#&A
			swi	OS_Claim

			mov	r0,#&B		;OS_BputV
			adr	r1,bputVLogRoutine
			mov	r2,#&B
			swi	OS_Claim

			mov	r0,#&C		;OS_GBPBV
			adr	r1,gbpbVLogRoutine
			mov	r2,#&C
			swi	OS_Claim

			mov	r0,#&D		;OS_FindV
			adr	r1,findVLogRoutine
			mov	r2,#&D
			swi	OS_Claim

			mov	r0,#&F		;OS_FSControlV
			adr	r1,fscontrolVLogRoutine
			mov	r2,#&F
			swi	OS_Claim

			ldmfd	r13!,{r0-r5,r12,pc}^

finalCode		stmfd	r13!,{r0-r2,r12,r14}

			mov	r0,#8		;OS_FileV
			adr	r1,fileVLogRoutine
			mov	r2,#8
			swi	OS_Release

			mov	r0,#9		;OS_ArgV
			adr	r1,argVLogRoutine
			mov	r2,#9
			swi	OS_Release

			mov	r0,#&A		;OS_BGetV
			adr	r1,bgetVLogRoutine
			mov	r2,#&A
			swi	OS_Release

			mov	r0,#&B		;OS_BputV
			adr	r1,bputVLogRoutine
			mov	r2,#&B
			swi	OS_Release

			mov	r0,#&C		;OS_GBPBV
			adr	r1,gbpbVLogRoutine
			mov	r2,#&C
			swi	OS_Release

			mov	r0,#&D		;OS_FindV
			adr	r1,findVLogRoutine
			mov	r2,#&D
			swi	OS_Release

			mov	r0,#&F		;OS_FSControlV
			adr	r1,fscontrolVLogRoutine
			mov	r2,#&F
			swi	OS_Release

			adr	r0,logNameS
			swi	SysLog_FlushLog

			ldmfd	r13!,{r0-r2,r12,pc}^

fileVLogRoutine		stmfd	r13!,{r0-r1,r14}

			adr	r0,fileVCallBack
			mov	r1,#42		; Who cares?
			swi	OS_AddCallBack

			ldmfd	r13!,{r0-r1,r14}
			movs	pc,r14


fileVCallBack		stmfd	r13!,{r0-r12,r14}
			mov	r6,r0		;preserve the condition code
			mov	r7,r1
			mov	r8,r2
			mov	r9,r3
			mov	r10,r4
			mov	r11,r5

			;bl	isAccessFileLogger

			;ldmeqfd	r13!,{r0-r2,r12,pc}^

			mov	r3,r6
			teq	r3,#255
			moveq	r3,#25
			cmp	r3,#25
			bgt	fileVLogUnknown
			cmp	r3,#0
			blt	fileVLogUnknown

			;this is horrid, there must be a nicer way...
			adr	r0,osFileConditionTable
			mov	r3,r3,lsl #2	;*4
			ldr	r1,[r0,r3]
			adr	r0,osFileCTableStartOffset
			add	r1,r1,r0
			ldr	r0,osFileCTableStartOffset
			sub	r1,r1,r0

			adr	r0,logNameS
			mov	r2,#PRIORITY
			swi	SysLog_LogMessage

			adr	r1,fileVNameS
			bl	logFormatted

			;this is horrid, there must be a nicer way...
			adr	r0,osFileRegsTable
			; assuming r3 not corrupted since previous table look up
			ldr	r1,[r0,r3]
			adr	r0,osFileRTableStartOffset
			add	r1,r1,r0
			ldr	r0,osFileRTableStartOffset
			sub	r1,r1,r0

			cmn	r1,#1
			blne	logFormatted

			bl	logSeperator

			ldmfd	r13!,{r0-r12,r14}
			movs	pc,r14

fileVLogUnknown		adr	r1,fileVUnKnownS
			bl	logFormatted
			ldmfd	r13!,{r0-r10,r12,pc}^

logSeperator		stmfd	r13!,{r0-r2,r14}
			adr	r0,logNameS
			adr	r1,logSeperatorS
			mov	r2,#PRIORITY
			swi	SysLog_LogMessage
			ldmfd	r13!,{r0-r2,r14}
			movs	pc,r14
logFormatted
; => r1 = format string
			stmfd	r13!,{r0-r3,r8-r12,r14}
			adr	r0,logNameS
			mov	r3,r13
			swi	SysLog_LogFormatted
			ldmfd	r13!,{r0-r3,r8-r12,r14}
			movs	pc,r14

argVLogRoutine		stmfd	r13!,{r0-r1,r14}

			adr	r0,argVCallBack
			mov	r1,#42		; Who cares?
			swi	OS_AddCallBack

			ldmfd	r13!,{r0-r1,r14}
			movs	pc,r14

argVCallBack		stmfd	r13!,{r0-r9,r12,r14}

			mov	r6,r0		;preserve the condition code
			mov	r7,r1
			mov	r8,r2
			mov	r9,r3

			;bl	isAccessFileLogger

			;ldmeqfd	r13!,{r0-r2,r12,pc}^

			mov	r3,r6
			teq	r3,#254
			moveq	r3,#9
			teq	r3,#255
			moveq	r3,#10
			cmp	r3,#10
			bgt	argVLogUnknown
			cmp	r3,#0
			blt	argVLogUnknown

			;this is horrid, there must be a nicer way...
			adr	r0,osArgsConditionTable
			mov	r3,r3,lsl #2	;*4
			ldr	r1,[r0,r3]
			adr	r0,osArgsCTableStartOffset
			add	r1,r1,r0
			ldr	r0,osArgsCTableStartOffset
			sub	r1,r1,r0

; this routine locks machine solid if swi below is uncommented, or
; if allowed to continue until reaching another swi :(
; I have little idea why.
; Doesn't seem to be an SVC/IRQ issue, and isn't a problem with the r1 pointer...
; Suggestions on a postcard to the usual address please ;-(

			adr	r0,logNameS
			mov	r2,#PRIORITY
			swi	SysLog_LogMessage

			adr	r1,argVHandleS
			bl	logFormatted

			;this is horrid, there must be a nicer way...
			adr	r0,osArgsRegsTable
			; assuming r3 not corrupted since previous table look up
			ldr	r1,[r0,r3]
			adr	r0,osArgsRTableStartOffset
			add	r1,r1,r0
			ldr	r0,osArgsRTableStartOffset
			sub	r1,r1,r0

			cmn	r1,#1
			blne	logFormatted

			bl	logSeperator

			ldmfd	r13!,{r0-r9,r12,r14}
			movs	pc,r14

argVLogUnknown		adr	r1,argVUnKnownS
			bl	logFormatted
			ldmfd	r13!,{r0-r9,r12,r14}
			movs	pc,r14

bgetVLogRoutine		stmfd	r13!,{r0-r1,r14}

			adr	r0,bgetVCallBack
			mov	r1,#42		; Who cares?
			swi	OS_AddCallBack

			ldmfd	r13!,{r0-r1,r14}
			movs	pc,r14

bgetVCallBack		stmfd	r13!,{r0-r2,r7,r12,r14}

			mov	r7,r1		;preserve filehandle

			adr	r1,bgetVS
			bl	logFormatted

			bl	logSeperator

			ldmfd	r13!,{r0-r2,r7,r12,r14}
			movs	pc,r14

bputVLogRoutine		stmfd	r13!,{r0-r1,r14}

			adr	r0,bputVCallBack
			mov	r1,#42		; Who cares?
			swi	OS_AddCallBack

			ldmfd	r13!,{r0-r1,r14}
			movs	pc,r14

bputVCallBack		stmfd	r13!,{r0-r2,r6-r7,r12,r14}

			mov	r6,r0		;preserve the byte
			mov	r7,r1		;preserve filehandle

			adr	r1,bputVS
			bl	logFormatted

			bl	logSeperator

			ldmfd	r13!,{r0-r2,r6-r7,r12,r14}
			movs	pc,r14

gbpbVLogRoutine		stmfd	r13!,{r0-r1,r14}

			adr	r0,gbpbVCallBack
			mov	r1,#42		; Who cares?
			swi	OS_AddCallBack

			ldmfd	r13!,{r0-r1,r14}
			movs	pc,r14

gbpbVCallBack		stmfd	r13!,{r0-r12,r14}

			mov	r7,r0
			mov	r8,r1
			mov	r9,r2
			mov	r10,r3
			mov	r11,r4

			cmp	r0,#12
			bgt	GBPBVLogUnknown
			cmp	r0,#1
			blt	GBPBVLogUnknown

			;this is horrid, there must be a nicer way...
			mov	r3,r0,lsl #2	;*4
			adr	r0,osGBPBConditionTable
			ldr	r1,[r0,r3]
			adr	r0,osGBPBCTableStartOffset
			add	r1,r1,r0
			ldr	r0,osGBPBCTableStartOffset
			sub	r1,r1,r0

			adr	r0,logNameS
			mov	r2,#PRIORITY
			swi	SysLog_LogMessage

			cmp	r7,#8
			adrgt	r1,GBPBdirNameS
			blgt	logFormatted
			adrgt	r1,GBPBmatchNameS
			blgt	logFormatted

			;this is horrid, there must be a nicer way...
			adr	r0,osGBPBRegsTable
			; assuming r3 not corrupted since previous table look up
			ldr	r1,[r0,r3]
			adr	r0,osGBPBRTableStartOffset
			add	r1,r1,r0
			ldr	r0,osGBPBRTableStartOffset
			sub	r1,r1,r0
			cmn	r1,#1
			blne	logFormatted

			bl	logSeperator

			ldmfd	r13!,{r0-r12,r14}
			movs	pc,r14

GBPBVLogUnknown		adr	r1,fileVUnKnownS
			bl	logFormatted
			ldmfd	r13!,{r0-r12,r14}
			movs	pc,r14

findVLogRoutine		stmfd	r13!,{r0-r1,r14}

			adr	r0,findVCallBack
			mov	r1,#42		; Who cares?
			swi	OS_AddCallBack

			ldmfd	r13!,{r0-r1,r14}
			movs	pc,r14

findVCallBack		stmfd	r13!,{r0-r6,r12,r14}

			mov	r4,r0		;preserve the condition code
			mov	r5,r1
			mov	r6,r2

			adr	r1,findVCloseS

			cmp	r0,#&0
			adrgt	r1,findVOpenExistReadS

			cmp	r0,#&40
			adrgt	r1,findVCreateS

			cmp	r0,#&80
			adrgt	r1,findVOpenExistWriteS

			bl	logFormatted
			bl	logSeperator

			ldmfd	r13!,{r0-r6,r12,r14}
			movs	pc,r14

fscontrolVLogRoutine	stmfd	r13!,{r0-r1,r14}

			adr	r0,fscontrolVCallBack
			mov	r1,#42		; Who cares?
			swi	OS_AddCallBack

			ldmfd	r13!,{r0-r1,r14}
			movs	pc,r14

fscontrolVCallBack	stmfd	r13!,{r0-r12,r14}

			mov	r7,r0
			mov	r8,r1
			mov	r9,r2
			mov	r10,r3
			mov	r11,r4

			cmp	r0,#57
			bgt	FSCVLogUnknown
			cmp	r0,#0
			blt	FSCVLogUnknown

			;this is horrid, there must be a nicer way...
			mov	r3,r0,lsl #2	;*4
			adr	r0,osFSCConditionTable
			ldr	r1,[r0,r3]
			adr	r0,osFSCCTableStartOffset
			add	r1,r1,r0
			ldr	r0,osFSCCTableStartOffset
			sub	r1,r1,r0

			adr	r0,logNameS
			mov	r2,#PRIORITY
			swi	SysLog_LogMessage

			ldmfd	r13!,{r0-r12,r14}
			movs	pc,r14

FSCVLogUnknown		adr	r1,FSCVUnKnownS
			bl	logFormatted
			ldmfd	r13!,{r0-r12,r14}
			movs	pc,r14

; it is obviously mildly important not to log stuff we are doing :)
isAccessFileLogger	stmfd	r13!,{r0-r2,r14}

; => r1 = filename to check
			adr	r2,pathCheckBuffer
isUsLoop		ldrb	r0,[r2],#1
			ldrb	r3,[r1],#1
			teq	r0,#0
			;teqne	r3,#0
			ldmeqfd	r13!,{r0-r2,r14}
			orreq	pc,r14,#1<<30	; set eq bit
			teq	r0,r3
			ldmnefd	r13!,{r0-r2,pc}
			b	isUsLoop

			ldmfd	r13!,{r0-r2,pc}^

logPathS		DCB	"<SysLog$LogDir>."
			ALIGN
logNameS		DCB	"FileLogger",0
			ALIGN

logSeperatorS		DCB	"",0
			ALIGN

; yeah, this should really be claimed at runtime
pathCheckBuffer		DBB	256
			ALIGN

 END
